package com.logicfishsoftware.wolfgo.owlcompiler;

/*
 * Copyright 2001-2005 The Apache Software Foundation.

 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.apache.maven.artifact.DependencyResolutionRequiredException;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.util.cli.CommandLineException;
import org.codehaus.plexus.util.cli.CommandLineUtils;
import org.codehaus.plexus.util.cli.Commandline;
import org.codehaus.plexus.util.cli.StreamConsumer;

/**
 * Goal runs the openrdf-alibaba owl compiler.
 * TODO Boolean flags being passed to the compiler are broken. 
 *
 * @goal owl-compiler
 * 
 * @phase process-sources
 * 
 * @requiresDependencyResolution compile+runtime
 * 
 */
public class OwlCompilerMojo
    extends AbstractMojo
{
    /**
     * Location of the output Jar file.
     * @parameter expression="${project.build.outputDirectory}/onto.jar"
     * @required
     */
    private File outputFile;

    /**
     * Locations of the ontology file.
     * @parameter 
     * @required
     */
    private String[] ontologyFiles;
 
    /**
     * Locations of the classpath jar files.
     * @parameter 
     */
    private String[] jarFiles;
    /**
     * Prefix all property names
     * @parameter 
     */
    private String prefix;
    /**
     * Extends Class
     * @parameter
     * @optional 
     */
    private String extendsClass;
    /**
     * Offline
     * @parameter expression="false"
     * @optional 
     */
    private boolean offline;
    /**
     * Follow
     * @parameter expression="true"
     * @optional 
     */
    private boolean follow;
    /**
     * When true, do not pluralise set property names
     * @parameter expression="false"
     * @optional 
     */
    private boolean singular;
    
    /**
     * @parameter default-value="${project}"
     */
    MavenProject mavenProject;

    /** 
     * @parameter default-value="${plugin.artifacts}" 
     */
    //private java.util.List<String> pluginClasspath;

    /**
     * @parameter default-value="-mx512m"
     */
    private List<String> vmArgs;
    
    @SuppressWarnings("unchecked")
	public void execute()
        throws MojoExecutionException
    {
    	getLog().info("Compiling ontologies <"+Arrays.toString(ontologyFiles)+">");

    	List<String> commands = new ArrayList<String>();
    	
    	Set<String> classPath = new HashSet<String>();
    	
    	try {
    		classPath.addAll(mavenProject.getCompileClasspathElements());
	    	classPath.addAll(mavenProject.getRuntimeClasspathElements());
		} catch (DependencyResolutionRequiredException e) {
			getLog().error(e);
			throw new MojoExecutionException("Error getting classpath elements.",e);
		}
    	String cp = StringUtils.join(classPath,File.pathSeparatorChar);
    	getLog().info("Classpath <" + cp + ">");
    	commands.add("-cp");
    	commands.add(cp);    	
    	
    	getLog().info("VM args <"+vmArgs+">");
    	commands.addAll(vmArgs);

    	commands.add(org.openrdf.repository.object.compiler.Compiler.class.getName());
    	
    	if(prefix!=null && !"".equals(prefix)) {
        	getLog().info("Prefix <"+prefix+">");
    		commands.add("-p");
    		commands.add(prefix);
    	}
    	
    	if(extendsClass!=null && !"".equals(extendsClass)) {
        	getLog().info("extends <"+extendsClass+">");
    		commands.add("-e");
    		commands.add(extendsClass);
    	}

    	
    	// TODO These args didn't work..?
    	getLog().info("Offline <"+offline+">");
    	if(offline)
    		commands.add("-o");
   		//commands.add(Boolean.toString(offline));

    	getLog().info("Follow imports <"+follow+">");
   		//if(follow) {
  		commands.add("-f");
//   		}
   		commands.add(Boolean.toString(follow));

    	getLog().info("Singular property names <"+singular+">");
   		if(singular)commands.add("-s");
//   		commands.add(Boolean.toString(singular));

   		if(jarFiles!=null) {
   	    	getLog().info("JAR Files <"+Arrays.toString(jarFiles)+">");
   			for (String jarFile : jarFiles) {
   				commands.add("-i");
   				commands.add(new File(jarFile).toURI().toString());
   			}
   		}
    	
    	getLog().info("Output File <"+outputFile+">");
    	commands.add("-j");
    	commands.add(outputFile.getAbsolutePath());

    	if(ontologyFiles!=null) {
        	getLog().info("Ontology Files <"+Arrays.toString(ontologyFiles)+">");
    		for(String ontoFile : ontologyFiles) {
        		//commands.add(ontoFile.getAbsolutePath());
    			commands.add(new File(ontoFile).toURI().toString());
        	}
    	}
    	
    	Commandline cl = new Commandline("java");
    	cl.addArguments(commands.toArray(new String[0]));
    	StreamConsumer systemOut = new StreamConsumer(){
			public void consumeLine(String line) {
				getLog().info(line);
			}};
		StreamConsumer systemErr = new StreamConsumer() {
			public void consumeLine(String line) {
				getLog().error(line);
			}};
		try {
			int retVal = CommandLineUtils.executeCommandLine(cl, systemOut, systemErr);
			if(retVal!=0) {
				throw new MojoExecutionException("OWL-Compiler failed.");
			}
		} catch (CommandLineException e) {
			getLog().error(e);
			throw new MojoExecutionException("Error running Alibaba OWL-Compiler.",e);
		}
    }
}
